#include <map>
#include "BeginConnInsDestHandler.h"
#include "BeginConnectOriDestHandler.h"
#include "EndConnectInsDestHandler.h"
#include "GlobalContext.h"

using namespace std;
using namespace log4cplus;

Logger BeginConnInsDestHandler::log=GetLogger(LOG4CPLUS_TEXT("BeginConnInsDestHandler"));

void BeginConnInsDestHandler::CreateSocketPostProcess(ClientContext &client,OVERLAPPED *ovl,SOCKET sock)
{
	map<string,string>::const_iterator iter=client.HttpRequest().Headers().find("Proxy-Connection");
	if(iter!=client.HttpRequest().Headers().end()&&iter->second==" Keep-Alive")
	{
		setsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,reinterpret_cast<char*>(1),sizeof(BOOL));
	}
	client.InitializeInsteadContext();
	client.InsteadContext().SetTempSock(sock);
	LOG4CPLUS_DEBUG_STR(log,LOG4CPLUS_TEXT("Instead server socket post process finished."));
}

const std::string& BeginConnInsDestHandler::DestinationServerName(ClientContext &client)
{
	return m_insteadUrl.ServerName();
}

const unsigned short BeginConnInsDestHandler::DestinationServerPort(ClientContext &client)
{
	return m_insteadUrl.ServerPort();
}

ITransHandler* BeginConnInsDestHandler::GetNextHandler()
{
	return new EndConnectInsDestHandler(m_insteadUrl);
}

ITransHandler::ExecuteResultCode BeginConnInsDestHandler::OnExecuteError(ClientContext &client,OVERLAPPED *ovl,ITransHandler::ExecuteResultCode executeResult)
{
	delete client.SetCurrentHandler(new BeginConnectOriDestHandler());
	client.FreeInsteadContext();
	LOG4CPLUS_DEBUG_STR(log,LOG4CPLUS_TEXT("Try to connect instead server failed(free instead context),try to connect original server."));
	::PostQueuedCompletionStatus(GlobalContext::Instance().IOCP(),0,static_cast<ULONG_PTR>(client.SequenceNo()),ovl);
	return ITransHandler::ExecuteOK;
}

ITransHandler::ExecuteResultCode BeginConnInsDestHandler::OnConnected(ClientContext &client,OVERLAPPED *ovl)
{
	::PostQueuedCompletionStatus(GlobalContext::Instance().IOCP(),0,static_cast<ULONG_PTR>(client.SequenceNo()),client.InsteadContext().TempOVL());
	return ITransHandler::ExecuteOK;
}